Slang

About

  • Slang .

  • Slang .

    • Experimental to wasm.

  • User Guide .

  • Playground .

    • OOP everywhere.

  • Alternative to HLSL

  • HLSL-like syntax but open & cross-platform.

  • Can compile to different shader languages.

  • Supports Vulkan, DirectX, CUDA, and more.

  • Smaller community than GLSL/HLSL.

  • Made by Shading Languages Working Group.

  • Supported by:

    • NVIDIA.

    • Adobe.

    • Autodesk.

    • Id Tech.

    • Valve.

  • "Slang is a shader language that has spent over 15 years in development at NVIDIA and solves many of the problems shader programmers face today. All the while supporting HLSL, GLSL, WSL, Metal and SPIR-V shaders."

  • Features :

    • Like HLSL, Slang uses parameters and return values for input and output with annotations to help describe what those variables relate to. The language includes many features to aid in graphics programming, like built-in vector and matrix primitives. Functions for operations like cross-products, matrix-vector products, auto differentiation for AI, and reflections around a vector are included.

    • The vector type is called float  with a number indicating the number of elements. For example, a 3D position would be stored in a float3 .

    • It is possible to access single components through members like .x  called the swizzle operator, but it’s also possible to create a new vector from multiple components at the same time.

      • For example, the expression float3(1.0,2.0, 3.0).xy  would result in float2 .

      • The constructors of vectors can also take combinations of vector objects and scalar values. For example, a float3  can be constructed with float3(float2(1.0, 2.0), 3.0) .

    • There are no instructions for bindings. Slang is designed to automatically infer the bindings by the order of declaration.

    • We’re calling our main function vertMain instead of main, this is because Slang and SPIR-V both support having multiple entry points in one file.

      • This is important when you’re dealing with pipelines which have more than just a single vert/frag shader combo.

      • Ray-tracing for instance, even for simple demos, would have four or more shaders all small yet needing their own file which can become cumbersome.

    • Another major feature of Slang is the ability to create shader libraries or modules.

    • It's best practice to keep shaders in a single file.

    • Type‐safe generics instead of text‐based macros.

      • Slang can auto-generate binding layouts for resources in Vulkan, deducing bindings by order rather than requiring the programmer to manually annotate each binding.

      • By default Slang emits explicit layout(set=… , binding=…)  qualifiers so that bindings are deterministic across optimization passes.

      • GLSL, on the other hand, normally requires the developer to write layout(set=N, binding=M)  themselves (or rely on Vulkan’s default assignment), which can change if the driver optimizes away resources.

    • It supports compile-time generics and interfaces.

      • So you can write, for example, a single shader template that works for many types, then specialize it statically for different material or light types.

    • Has a Reflection API built in (through its compiler interface) that lets applications introspect shader parameters and resource layouts at runtime.

    • SLANG is a shading language that compiles to multiple backends (HLSL, GLSL, SPIR-V), but it supports OOP features  (classes, interfaces, generics).

      • GLSL avoids OOP.

Compiling

slangc shader.slang -target spirv -profile spirv_1_4 -emit-spirv-directly -fvk-use-entrypoint-name -entry vertMain -entry fragMain -o slang.spv

Examples

  • Hardcoded triangle :

    • Vertex and Fragment:

    static float2 positions[3] = float2[](
        float2(0.0, -0.5),
        float2(0.5, 0.5),
        float2(-0.5, 0.5)
    );
    
    struct VertexOutput {
        float4 sv_position : SV_Position;
    };
    
    [shader("vertex")]
    VertexOutput vertMain(uint vid : SV_VertexID) {
        VertexOutput output;
        output.sv_position = float4(positions[vid], 0.0, 1.0);
        return output;
    }
    
    [shader("fragment")]
    float4 fragMain() : SV_Target
    {
        return float4(1.0, 0.0, 0.0, 1.0);
    }